package com.ruoyi.repairCar.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.repairCar.domain.dto.RescueMessage;
import com.ruoyi.repairCar.domain.dto.RescueRequestDTO;
import com.ruoyi.repairCar.service.RescueService;
import lombok.RequiredArgsConstructor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
@RequiredArgsConstructor
public class RescueServiceImpl implements RescueService {
    private final RabbitTemplate rabbitTemplate;
    private final StringRedisTemplate redisTemplate;
    private final ObjectMapper objectMapper;

    private static final String RESCUE_EXCHANGE = "rescue.exchange";
    private static final String MQ_PREFIX = "rescue.task:";

    @Override
    public void processRescueRequest(RescueRequestDTO request) {
        try {
            // 构建MQ消息
            RescueMessage message = convertToMessage(request);

            // 存储初始状态到Redis
            String messageKey = MQ_PREFIX + message.getMessageId();
            Map<String, String> stateMap = new HashMap<>();
            stateMap.put("current_range", String.valueOf(request.getMqConfig().getInitialRange()));
            stateMap.put("retry_count", "0");
            stateMap.put("status", "PENDING");

            redisTemplate.opsForHash().putAll(messageKey, stateMap);
            redisTemplate.expire(messageKey, 1, TimeUnit.HOURS);

            // 发送初始消息到MQ
            sendToMQ(message, request.getMqConfig().getInitialRange());

        } catch (JsonProcessingException e) {
            throw new RuntimeException("消息处理失败", e);
        }
    }

    private RescueMessage convertToMessage(RescueRequestDTO request) {
        return RescueMessage.builder()
                .messageId(UUID.randomUUID().toString())
                .rescueType(request.getRescueType())
                .location(convertGeoLocation(request.getGeolocation()))
                .memberId(request.getMemberId())
                .vehicleInfo(RescueMessage.VehicleInfo.builder()
                        .model(request.getVehicleModel())
                        .number(request.getVehicleNumber())
                        .build())
                .description(request.getSituationExplanation())
                .timestamp(System.currentTimeMillis())
                .build();
    }

    private RescueMessage.GeoLocation convertGeoLocation(RescueRequestDTO.GeoLocation source) {
        return RescueMessage.GeoLocation.builder()
                .latitude(source.getLatitude())
                .longitude(source.getLongitude())
                .coordinateSystem(source.getCoordinateSystem())
                .build();
    }

    private void sendToMQ(RescueMessage message, int range) throws JsonProcessingException {
        String routingKey = String.format("rescue.%dkm", range);
        rabbitTemplate.convertAndSend(
                RESCUE_EXCHANGE,
                routingKey,
                objectMapper.writeValueAsString(message),
                msg -> {
                    // 设置消息TTL（单位毫秒）
                    msg.getMessageProperties().setExpiration(
                            String.valueOf(range == 3 ? 10000 : 15000));
                    return msg;
                }
        );
    }
}